package com.fancy.projecty.A_流程相关;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.*;

/**
 * 真实应用场景：用户想查看这个请假流程具体有哪些步骤要走？
 * <p>
 * 需求：
 * *
 * 1.从Activiti的act_ge_bytearray表中读取两个资源文件
 * 2.将两个资源文件保存到路径：   G:\Activiti7开发计划\Activiti7-day03\资料
 * <p>
 * 技术方案：
 * 1.第一种方式使用actviti的api来实现(最方便)
 * 2.第二种方式：其实就是原理层面，可以使用jdbc的对blob类型，clob类型数据的读取，并保存
 * IO流转换，最好commons-io.jar包可以轻松解决IO操作
 * <p>
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class F_保存流程图到本地 {


	@Autowired
	/*执行管理、包括启动、推进、删除流程实例等操作*/
	private RuntimeService runtimeService;
	@Autowired
	/*任务管理,可以做任务的查询的*/
	private TaskService taskService;


	@Autowired
	/*管理流程定义,部署相关的Service*/
	private RepositoryService repositoryService;

	@Test
	public void c_保存流程资源文件到本地() throws IOException {
		//3.得到查询器:ProcessDefinitionQuery对象
		ProcessDefinitionQuery processDefinitionQuery = this.repositoryService.createProcessDefinitionQuery();
		//4.设置查询条件
		//参数是流程定义的key
		ProcessDefinitionQuery holiday = processDefinitionQuery.processDefinitionKey("holiday");

		//5.执行查询操作,查询出想要的流程定义
		//因为holiday流程只有一个,所以就用singleResult() 获取一个流程结果
		ProcessDefinition processDefinition = processDefinitionQuery.singleResult();

		if (processDefinition != null) {
			//6.通过流程定义信息，得到部署ID
			String deploymentId = processDefinition.getDeploymentId();
			//7.通过repositoryService的方法,实现读取图片信息及bpmn文件信息(输入流)
			//getResourceAsStream()方法的参数说明：第一个参数部署id,第二个参数代表资源名称
			//processDefinition.getDiagramResourceName() 代表获取png图片资源的名称
			//processDefinition.getResourceName()代表获取bpmn文件的名称
			InputStream pngIs = repositoryService
					.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
			InputStream bpmnIs = repositoryService
					.getResourceAsStream(deploymentId, processDefinition.getResourceName());

			//8.构建出OutputStream流
			//processDefinition.getDiagramResourceName() 这个是获取存数据库是什么名字,这个就是什么名字

			String basePath = "C:\\Activiti7开发计划\\资料\\";

			// 如果不存在就创建这个路径下的文件夹
			// 不创建的话会抛出异常出来
			File file = new File(basePath);
			if (!file.exists()) {
				file.mkdirs();
			}
			/* 需要注意的是, 如果当前资源下有这个文件的话,
			会直接被覆盖掉
			*/
			OutputStream pngOs =
					new FileOutputStream(basePath + processDefinition.getDiagramResourceName());
			//processDefinition.getResourceName 获取 bpmn文件的名字
			OutputStream bpmnOs =
					new FileOutputStream(basePath + processDefinition.getResourceName());

			//9.输入流，输出流的转换  commons-io-xx.jar中的方法
			IOUtils.copy(pngIs, pngOs);
			IOUtils.copy(bpmnIs, bpmnOs);
			//10.关闭流
			pngOs.close();
			bpmnOs.close();
			pngIs.close();
			bpmnIs.close();
		} else {
			System.err.println("流程为空");
		}
	}

}
